﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using Dapper;
using Dapper.Contrib.Extensions;

namespace EC.Application.Impl
{
    using EC.Application.Interface;

    using EC.Entity;
    using EC.Entity.Enum;
    using EC.Entity.Query;
    using EC.Entity.Request.Settle;
    using EC.Entity.Response.Settle;
    using EC.Entity.Tables;
    using EC.Util;

    /// <summary>
    /// 结算接口实现
    /// </summary>
    public class SettleServiceImpl : SettleService
    {
        #region 注入
        /// <summary>
        /// 数据接口
        /// </summary>
        private readonly IDBSession _dbSession;


        /// <summary>
        /// 数据库上下文
        /// </summary>
        /// <param name="context">数据库上下文</param>
        public SettleServiceImpl(IDBSession dbSession)
        {
            _dbSession = dbSession;
        }
        #endregion


        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="id">编号</param>
        /// <returns></returns>
        public SettleResponse Get(int id)
        {
            var model = _dbSession.DbConnection.QueryFirst<SettleResponse>("select * from settle where Id=@Id", new { Id = id });
            if (model != null)
            {
                return model;
            }

            return null;
        }

        /// <summary>
        /// 更新状态
        /// </summary>
        /// <returns></returns>
        public JResult Audit(AuditRequest request)
        {
            var response = new JResult()
            {
                Success = false
            };

            try
            {
                var settle = _dbSession.DbConnection.QueryFirst<Settle>("select * from settle where Id=@Id", new { Id = request.Id });
                if (settle == null)
                {
                    throw new Exception("结算记录不存在.");
                }

                if (settle.Status != (int)SettleStatus.未处理)
                {
                    throw new Exception("已状态无法操作");
                }

                if (settle.HandBy > 0)
                {
                    throw new Exception("已锁定用户");
                }

                var updateSql = "UPDATE settle SET Status=@Status,HandBy=@HandBy WHERE Id=@Id";

                int result = _dbSession.DbConnection.Execute(updateSql, new { Status = request.Status, HandBy = request.UserId, Id = request.Id });
                if (result <= 0)
                {
                    throw new Exception("更新失败");
                }

                response.Success = true;
                response.Message = "操作成功.";
            }
            catch (Exception ex)
            {
                response.Message = ex.Message;
            }

            return response;
        }

        /// <summary>
        /// 确认打款
        /// </summary>
        /// <returns></returns>
        public JResult Confirm(AuditRequest request)
        {
            var response = new JResult()
            {
                Success = false
            };

            try
            {
                var settle = _dbSession.DbConnection.QueryFirst<Settle>("select * from settle where Id=@Id", new { Id = request.Id });
                if (settle == null)
                {
                    throw new Exception("结算记录不存在.");
                }

                if (settle.Status != (int)SettleStatus.处理中)
                {
                    throw new Exception("已状态无法操作");
                }

                if (settle.HandBy != request.UserId)
                {
                    throw new Exception("无法操作,你并非锁定用户");
                }

                var updateSql = "UPDATE settle SET Status=@Status,HandTime=@HandTime,HandBy=@HandBy WHERE Id=@Id";

                int result = _dbSession.DbConnection.Execute(updateSql, new { Status = request.Status, HandBy = request.UserId, HandTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), Id = request.Id });
                if (result <= 0)
                {
                    throw new Exception("更新失败");
                }

                response.Success = true;
                response.Message = "操作成功.";
            }
            catch (Exception ex)
            {
                response.Message = ex.Message;
            }

            return response;
        }

        /// <summary>
        /// 驳回
        /// </summary>
        /// <returns></returns>
        public JResult Reject(AuditRequest request)
        {
            var response = new JResult()
            {
                Success = false
            };

            try
            {
                //事务开始
                _dbSession.Begin();

                var settle = _dbSession.DbConnection.QueryFirst<Settle>("select * from settle where Id=@Id", new { Id = request.Id }, _dbSession.DbTransaction);
                if (settle == null)
                {
                    throw new Exception("结算记录不存在.");
                }

                if (settle.Status != (int)SettleStatus.处理中)
                {
                    throw new Exception("已状态无法操作");
                }

                if (settle.HandBy != request.UserId)
                {
                    throw new Exception("无法操作,你并非锁定用户");
                }
                //商户
                var merchants = _dbSession.DbConnection.Query<Merchant>("select * from merchant where Id=@Id", new { Id = settle.MerchantId }, _dbSession.DbTransaction);

                var merchant = merchants.FirstOrDefault();
                if (merchant == null)
                {
                    throw new Exception("暂无记录.");
                }

                var total = settle.Amount + settle.Fee;

                //存款余额日志
                var depositBalanceLog = new BalanceLog()
                {
                    MerchantId = settle.MerchantId,
                    Source = (int)BalanceLogSource.存款余额,
                    Type = (int)BalanceLogType.加,
                    Amount = total,
                    BeforeBalance = merchant.DepositBalance,
                    AfterBalance = merchant.DepositBalance + total,
                    Remark = "驳回",
                    CreatedBy = request.UserId,
                    CreatedDate = DateTime.Now
                };
                //新增
                long depositBalanceLogResultId = _dbSession.DbConnection.Insert<BalanceLog>(depositBalanceLog, _dbSession.DbTransaction);

                if (depositBalanceLogResultId <= 0)
                {
                    throw new Exception("新增存款余额日志失败.");
                }


                var updateSql = "UPDATE settle SET Status=@Status,HandTime=@HandTime,HandBy=@HandBy WHERE Id=@Id";

                int result = _dbSession.DbConnection.Execute(updateSql, new { Status = request.Status, HandTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), HandBy = request.UserId, Id = request.Id }, _dbSession.DbTransaction);
                if (result <= 0)
                {
                    throw new Exception("更新失败");
                }

                //余额
                int merchantUpdateStatus = _dbSession.DbConnection.Execute("UPDATE merchant SET DepositBalance=DepositBalance+@Amount WHERE Id=@Id", new { Amount = total, Id = settle.MerchantId }, _dbSession.DbTransaction);
                if (result <= 0)
                {
                    throw new Exception("更新账户失败");
                }
                response.Success = true;
                response.Message = "操作成功.";

                //提交事务
                _dbSession.Commit();
            }
            catch (Exception ex)
            {
                _dbSession.Rollback();

                response.Message = ex.Message;
            }

            return response;
        }

        /// <summary>
        /// 备注
        /// </summary>
        /// <returns></returns>
        public JResult SaveRemark(SettleRemarkRequest request)
        {
            var response = new JResult()
            {
                Success = false
            };

            try
            {
                var settle = _dbSession.DbConnection.QueryFirst<Settle>("select * from settle where Id=@Id", new { Id = request.Id });
                if (settle == null)
                {
                    throw new Exception("结算记录不存在.");
                }


                if (settle.HandBy != request.UserId)
                {
                    throw new Exception("无法操作,你并非锁定用户");
                }

                var updateSql = "UPDATE settle SET Remark=@Remark WHERE Id=@Id";

                int result = _dbSession.DbConnection.Execute(updateSql, new { Remark = request.Remark, Id = request.Id });
                if (result <= 0)
                {
                    throw new Exception("更新失败");
                }

                response.Success = true;
                response.Message = "操作成功.";
            }
            catch (Exception ex)
            {
                response.Message = ex.Message;
            }

            return response;
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
        public DataGrid<SettleQueryResponse> GetPager(SettleQuery query)
        {
            var pageIndex = 0;

            if (query.Page.HasValue && query.Page.Value == 1)
            {
                pageIndex = 0;
            }
            else
            {
                pageIndex = query.Page.Value;
            }

            var files = "s.Id,s.MerchantId,s.BankName,s.CardName,s.CardNumber,s.Amount,s.Fee,s.HandTime,(SELECT Account FROM user WHERE Id=s.HandBy) AS _HandBy,s.Status,s.Remark,u.Account AS _CreatedBy,s.CreatedDate";
            var tableName = "settle s INNER JOIN `user` u ON s.CreatedBy=u.Id";
            var orderby = "ORDER BY s.Id DESC";
            var where = $"where s.MerchantId in ({string.Join(", ", query.MerchantIds)})";

            #region 条件
            if (query.Status.HasValue)
            {
                where += string.Format(" and s.Status={0}", query.Status);
            }

            if (!string.IsNullOrEmpty(query.StartTime) && !string.IsNullOrEmpty(query.EndTime))
            {
                where += string.Format(" And s.CreatedDate between '{0}' and '{1}'", query.StartTime, query.EndTime);
            }
            #endregion

            var sb = new StringBuilder();

            sb.AppendFormat("SELECT COUNT(1) FROM {0} {1};", tableName, where);
            sb.AppendFormat("SELECT {0} FROM {1} {2} {3} LIMIT {4},{5};", files, tableName, where, orderby, query.Page.Value - 1, query.Rows.Value);


            //总计
            var countSql = string.Format("SELECT sum(Fee) as FeeTotal,sum(Amount) AS JieSuanAmount FROM {1} {2};", files, tableName, where);

            var jieSuanTotal = new decimal(0);
            var feeTotal = new decimal(0);

            var settleQueryTotal = _dbSession.DbConnection.Query<SettleQueryTotal>(countSql);
            if (settleQueryTotal != null && settleQueryTotal.Any())
            {
                var depositOrder = settleQueryTotal.FirstOrDefault();
                if (depositOrder != null)
                {
                    jieSuanTotal = depositOrder.JieSuanAmount;
                    feeTotal = depositOrder.FeeTotal;
                }
            }

            using (var multi = _dbSession.DbConnection.QueryMultiple(sb.ToString()))
            {
                var count = multi.ReadFirst<int>();

                var list = multi.Read<SettleQueryResponse>();

                #region
                var amountSum = new decimal(0);
                var feeSum = new decimal(0);

                var rows = new List<SettleQueryResponse>();

                foreach (var item in list)
                {
                    //小计
                    amountSum += item.Amount;
                    feeSum += item.Fee;

                    var model = new SettleQueryResponse();
                    model.Id = item.Id;
                    model.MerchantName = "";
                    model.BankName = item.BankName;
                    model.CardName = item.CardName;
                    model.CardNumber = item.CardNumber;
                    model._Amount = item.Amount.ToString("#0.00");
                    model._Fee = item.Fee.ToString("#0.00");
                    model._HandTime = item.HandTime.HasValue ? item.HandTime.Value.ToString("yyyy-MM-dd HH:mm:ss") : "";
                    model._HandBy = item._HandBy;
                    model.Status = item.Status;
                    model.Remark = item.Remark;
                    model._CreatedBy = item._CreatedBy;
                    model._CreatedDate = item.CreatedDate.ToString("yyyy-MM-dd HH:mm:ss");
                    rows.Add(model);
                }
                //定义页脚
                var footers = new List<SettleQueryResponse>() {
                    new SettleQueryResponse()
                    {
                        Id=-1,
                        CardNumber = "小计",
                        _Amount=amountSum.ToString("#0.00"),
                        _Fee=feeSum.ToString("#0.00"),
                        Status=-1,
                    },
                    new SettleQueryResponse()
                    {
                        Id=-1,
                        CardNumber = "总计",
                        _Amount=jieSuanTotal.ToString("#0.00"),
                        _Fee=feeTotal.ToString("#0.00"),
                        Status=-1,
                    }
                };
                #endregion

                return new DataGrid<SettleQueryResponse>()
                {
                    Total = count,
                    Rows = rows,
                    Footer = footers,
                    Success = true
                };
            }
        }
    }
}
